/*
 
 Copyright (c) 2004 PXI Project Team
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in the
 Software without restriction, including without limitation the rights to use,
 copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
 Software, and to permit persons to whom the Software is furnished to do so,
 subject to the following conditions:
 
 The above copyright notice and this permission notice shall be included in all copies
 or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 */

//  PXIButton.m
//  PXIView
//
//  last changed by: creysoft

/* Implementation of PXIButtonView
	This is the core class for drawing HyperCard style buttons.

	It's not as modular as I'd like, but it works, so we'll just have to
	live with it for now.

*/

#import "PXIButtonView.h"

extern PXIMasterController * gPXIWorld;

@implementation PXIButtonView

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.

		// Initializations (Why aren't these method calls?)
		partStyle = PXIPartStyleRectangle;
		enabled = true;
		hilite = false;
		visible = true;
		showName = true;
		textAlign = PXITextAlignCenter;
		textSize = 12;
		titleWidth = 0;
		
		[self setFontName:@"Charcoal"];
		
		// Load all the images and cache them.
		// These will only be loaded once.
		defcorners = [NSImage imageNamed: @"defcrn"];
		stdcorners = [NSImage imageNamed: @"stdcrn"];
		rndcorners = [NSImage imageNamed: @"rndcrn"];
		hl_defcorners = [NSImage imageNamed: @"hdefcrn"];
		hl_stdcorners = [NSImage imageNamed: @"hstdcrn"];
		hl_rndcorners = [NSImage imageNamed: @"hrndcrn"];

		checkon = [NSImage imageNamed: @"chkon"];
		checkoff = [NSImage imageNamed: @"chkoff"];
		checkclick = [NSImage imageNamed: @"chkclk"];

		radioon = [NSImage imageNamed: @"radon"];
		radiooff = [NSImage imageNamed: @"radoff"];
		radioclick = [NSImage imageNamed: @"radclk"];		
		popuparrow = [NSImage imageNamed: @"poparrow"];		
		
		whitegraypat = [NSImage imageNamed: @"wgray"];
			
    }
    return self;
}

- (void)viewDidMoveToWindow
{
	// We need this so we can get mouse tracking.
	myTrackingTag = [self addTrackingRect:[self bounds] owner:self userData:nil assumeInside:NO];	
}

- (void)viewWillMoveToWindow:(NSWindow*)newWindow
{
	[self removeTrackingRect:myTrackingTag];
}

- (NSString *)fontName {
    return [[fontName retain] autorelease];
}

- (void)setFontName:(NSString *)newFontname {
    if (fontName != newFontname) {
        [fontName release];
        fontName = [newFontname copy];
    }
}

- (NSString *)partName {
    return [[partName retain] autorelease];
}

- (void)setPartName:(NSString *)newPartname {
    if (partName != newPartname) {
        [partName release];
        partName = [newPartname copy];
    }
}

- (int)partStyle {
    return partStyle;
}

- (void)setPartStyle:(int)newPartstyle {
    if (partStyle != newPartstyle) {
        partStyle = newPartstyle;
    }
}

- (BOOL)visible {
    return visible;
}

- (void)setVisible:(BOOL)newVisible {
    if (visible != newVisible) {
        visible = newVisible;
    }
}

- (BOOL)enabled {
    return enabled;
}

- (void)setEnabled:(BOOL)newEnabled {
    if (enabled != newEnabled) {
        enabled = newEnabled;
    }
}

- (BOOL)autoHilite {
    return autoHilite;
}

- (void)setAutoHilite:(BOOL)newAutohilite {
    if (autoHilite != newAutohilite) {
        autoHilite = newAutohilite;
    }
}

- (BOOL)hilite {
    return hilite;
}

- (void)setHilite:(BOOL)newHilite {
    if (hilite != newHilite) {
        hilite = newHilite;
    }
}

- (BOOL)showName {
    return showName;
}

- (void)setShowName:(BOOL)newShowname {
    if (showName != newShowname) {
        showName = newShowname;
    }
}

- (int)textAlign {
    return textAlign;
}

- (void)setTextAlign:(int)newTextalign {
    if (textAlign != newTextalign) {
        textAlign = newTextalign;
    }
}

- (int)textSize {
    return textSize;
}

- (void)setTextSize:(int)newTextsize {
    if (textSize != newTextsize) {
        textSize = newTextsize;
    }
}

- (int)titleWidth {
    return titleWidth;
}

- (void)setTitleWidth:(int)newTitlewidth {
    if (titleWidth != newTitlewidth) {
        titleWidth = newTitlewidth;
    }
}

- (BOOL)isFlipped
{
	return NO;
}

- (void)drawRect:(NSRect)rect {
    // Drawing code here.
	
	// Set up my drawing buffer.
	NSImage * gbuffer = [[NSImage alloc] initWithSize:rect.size];
	[gbuffer lockFocus];
	
	// Set up adjusted bounding rects.
	NSRect trueRect = NSMakeRect( rect.origin.x + 0.5, rect.origin.y + 0.5, rect.size.width - 1, rect.size.height - 1 );
	NSRect nr;
	
	// Set up disabled pattern.
	NSColor * myDisabledOverlay = [NSColor colorWithPatternImage:whitegraypat];
	NSColor * myForeColor = [NSColor blackColor];
	NSColor * myFontColor;
	// Fix for check boxes, radio buttons, and popups
	if ( partStyle == PXIPartStyleCheckBox || partStyle == PXIPartStyleRadioButton || partStyle == PXIPartStylePopup )
	{ 
		myFontColor = [NSColor blackColor];
	}
	else
	{
		myFontColor = ( [self hilite] ? [NSColor whiteColor] : [NSColor blackColor] );
	}
	
	// Set the default drawing color.
	[myForeColor set];
	
	// Set up font attributes.
	//NSDictionary* attrs = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont fontWithName:[self fontName] size: [self textSize]], NSFontAttributeName, myFontColor, NSForegroundColorAttributeName, nil];
	// Set up font attributes.
	NSFont* fnt = [NSFont fontWithName:[self fontName] size: [self textSize]];
	if( !fnt )
		fnt = [NSFont boldSystemFontOfSize: [self textSize]];
	if( !fnt )
		fnt = [NSFont boldSystemFontOfSize: [NSFont systemFontSize]];
	NSDictionary* attrs = [NSDictionary dictionaryWithObjectsAndKeys: fnt, NSFontAttributeName, myFontColor, NSForegroundColorAttributeName, nil];
	
	// Set up alignment.
	NSPoint titleRect;
	
	switch ( [self textAlign] )
	{
	case PXITextAlignLeft:
		titleRect = NSMakePoint( trueRect.origin.x + 8, trueRect.origin.y + ( trueRect.size.height / 2 ) - ( [[self partName] sizeWithAttributes:attrs].height / 2 ) );
		break;
	case PXITextAlignCenter:
		titleRect = NSMakePoint( trueRect.origin.x + ( trueRect.size.width / 2 ) - ( [[self partName] sizeWithAttributes:attrs].width / 2 ), trueRect.origin.y + ( trueRect.size.height / 2 ) - ( [[self partName] sizeWithAttributes:attrs].height / 2 ) );
		break;
	case PXITextAlignRight:
		titleRect = NSMakePoint( trueRect.origin.x + trueRect.size.width - 8, trueRect.origin.y + ( trueRect.size.height / 2 ) - ( [[self partName] sizeWithAttributes:attrs].height / 2 ) );
		break;
	}
	
	[[NSGraphicsContext currentContext] setShouldAntialias:NO];
	
	if ( ! [ self hilite ] )
	{
		
		/********************************************************************
							NORMAL DRAWING ROUTINES
        ********************************************************************/
		
		switch ( [self partStyle] )
		{
		case PXIPartStyleTransparent: // Transparent
			[myFontColor set];
			[[self partName] drawAtPoint:titleRect withAttributes:attrs];
			
			break;
		case PXIPartStyleOpaque: // Opaque
			[[NSColor whiteColor] set];
			[NSBezierPath fillRect:trueRect];
			[myFontColor set];
			[[self partName] drawAtPoint:titleRect withAttributes:attrs];
			
			break;
		case PXIPartStyleRectangle: // Rectangle
			[NSBezierPath strokeRect:trueRect];
			[myFontColor set];
			[[self partName] drawAtPoint:titleRect withAttributes:attrs];
				
			break;
			
		case PXIPartStyleRoundRect: // Round Rect
			
			// Draw a round rect button.
			
			// Draw opaque interior.
			[[NSColor whiteColor] set];
			[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + 7, trueRect.origin.y, trueRect.size.width - 14, trueRect.size.height ) ];
			[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x, trueRect.origin.y + 7, trueRect.size.width, trueRect.size.height - 14 ) ];
			
			[myForeColor set];
			
			// Draw corners
			[rndcorners compositeToPoint:NSMakePoint( 0, 0 ) fromRect:NSMakeRect( 0, 0, 7, 7 ) operation:NSCompositeSourceOver];
			[rndcorners compositeToPoint:NSMakePoint( 0, rect.origin.y + rect.size.height - 7 ) fromRect:NSMakeRect( 0, 7, 7, 7 ) operation:NSCompositeSourceOver];
			[rndcorners compositeToPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, 0 ) fromRect:NSMakeRect( 7, 0, 7, 7 ) operation:NSCompositeSourceOver];
			[rndcorners compositeToPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, rect.origin.y + rect.size.height - 7 ) fromRect:NSMakeRect( 7, 7, 7, 7 ) operation:NSCompositeSourceOver];
			
			// Draw Outline
			[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 7, rect.origin.y + rect.size.height - 0.5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, rect.origin.y + rect.size.height - 0.5  ) ];
			[[NSBezierPath setDefaultLineWidth:2] strokeLineFromPoint:NSMakePoint( rect.origin.x + rect.size.width - 0.5, 7 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 0.5, rect.origin.y + rect.size.height - 7  ) ];
			[[NSBezierPath setDefaultLineWidth:2] strokeLineFromPoint:NSMakePoint( 7, 0.5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, 0.5 ) ];
			[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 0.5, 7 ) toPoint:NSMakePoint( 0.5, rect.origin.y + rect.size.height - 7 ) ];

			[myFontColor set];
			[[self partName] drawAtPoint:titleRect withAttributes:attrs];
			
			break;	
			
		case PXIPartStyleShadow:
			// Draw a shadow button.
			[myForeColor set];
			[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + 2, trueRect.origin.y, trueRect.size.width - 2, trueRect.size.height - 2)];
			[[NSColor whiteColor] set];
			[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x, trueRect.origin.y + 1, trueRect.size.width - 1, trueRect.size.height - 1)];
			[myForeColor set];
			[NSBezierPath strokeRect:NSMakeRect( trueRect.origin.x, trueRect.origin.y + 1, trueRect.size.width - 1, trueRect.size.height - 1)];

			[myFontColor set];
			[[self partName] drawAtPoint:titleRect withAttributes:attrs];

			break;				
			
		case PXIPartStyleCheckBox:
			// Draw a check box.
			[checkoff compositeToPoint:NSMakePoint( 3, ( trueRect.size.height / 2 ) - 6 ) operation:NSCompositeCopy];

			titleRect = NSMakePoint( trueRect.origin.x + 19, trueRect.origin.y + ( trueRect.size.height / 2 ) - ( [[self partName] sizeWithAttributes:attrs].height / 2 ) );
			[[NSColor blackColor] set];
			[[self partName] drawAtPoint:titleRect withAttributes:attrs];
			
			break;
			
		case PXIPartStyleRadioButton:
			// Draw a radio button.
			[radiooff compositeToPoint:NSMakePoint( 3, ( trueRect.size.height / 2 ) - 6 ) operation:NSCompositeCopy];

			titleRect = NSMakePoint( trueRect.origin.x + 19, trueRect.origin.y + ( trueRect.size.height / 2 ) - ( [[self partName] sizeWithAttributes:attrs].height / 2 ) );
			[[NSColor blackColor] set];
			[[self partName] drawAtPoint:titleRect withAttributes:attrs];
			
			break;
			
		case PXIPartStyleStandard:
			// Draw a standard button.
			
			// Draw opaque interior.
			[[NSColor whiteColor] set];
			[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + 7, trueRect.origin.y, trueRect.size.width - 14, trueRect.size.height ) ];
			[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x, trueRect.origin.y + 7, trueRect.size.width, trueRect.size.height - 14 ) ];		
			
			[myForeColor set];
			
			// Draw corners
			[stdcorners compositeToPoint:NSMakePoint( 0, 0 ) fromRect:NSMakeRect( 0, 0, 7, 7 ) operation:NSCompositeSourceOver];
			[stdcorners compositeToPoint:NSMakePoint( 0, rect.origin.y + rect.size.height - 7 ) fromRect:NSMakeRect( 0, 7, 7, 7 ) operation:NSCompositeSourceOver];
			[stdcorners compositeToPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, 0 ) fromRect:NSMakeRect( 7, 0, 7, 7 ) operation:NSCompositeSourceOver];
			[stdcorners compositeToPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, rect.origin.y + rect.size.height - 7 ) fromRect:NSMakeRect( 7, 7, 7, 7 ) operation:NSCompositeSourceOver];
			
			// Draw Outline
			[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 7, 1 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, 0.5 ) ];
			[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 7, rect.origin.y + rect.size.height - 0.5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, rect.origin.y + rect.size.height - 0.5 ) ];
			[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 0, 7 ) toPoint:NSMakePoint( 0.5, rect.origin.y + rect.size.height - 7 ) ];
			[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( rect.origin.x + rect.size.width - 0.5, 7 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 0.5, rect.origin.y + rect.size.height - 7  ) ];

			[myFontColor set];
			[[self partName] drawAtPoint:titleRect withAttributes:attrs];
			
			break;
		case PXIPartStyleDefault:		
			// Draw a default button.

			// Draw opaque interior.
			[[NSColor whiteColor] set];
			[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + 7, trueRect.origin.y, trueRect.size.width - 14, trueRect.size.height ) ];
			[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x, trueRect.origin.y + 7, trueRect.size.width, trueRect.size.height - 14 ) ];
			
			[myForeColor set];

			// Draw corners
			[defcorners compositeToPoint:NSMakePoint( 0, 0 ) fromRect:NSMakeRect( 0, 0, 7, 7 ) operation:NSCompositeSourceOver];
			[defcorners compositeToPoint:NSMakePoint( 0, rect.origin.y + rect.size.height - 7 ) fromRect:NSMakeRect( 0, 7, 7, 7 ) operation:NSCompositeSourceOver];
			[defcorners compositeToPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, 0 ) fromRect:NSMakeRect( 7, 0, 7, 7 ) operation:NSCompositeSourceOver];
			[defcorners compositeToPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, rect.origin.y + rect.size.height - 7 ) fromRect:NSMakeRect( 7, 7, 7, 7 ) operation:NSCompositeSourceOver];
			
			// Draw Outline
			[[NSBezierPath setDefaultLineWidth:3] strokeLineFromPoint:NSMakePoint( 7, 1.5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, 1.5 ) ];
			[[NSBezierPath setDefaultLineWidth:3] strokeLineFromPoint:NSMakePoint( 7, rect.origin.y + rect.size.height - 1.5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, rect.origin.y + rect.size.height - 1.5  ) ];
			[[NSBezierPath setDefaultLineWidth:3] strokeLineFromPoint:NSMakePoint( 1.5, 7 ) toPoint:NSMakePoint( 1.5, rect.origin.y + rect.size.height - 7 ) ];
			[[NSBezierPath setDefaultLineWidth:3] strokeLineFromPoint:NSMakePoint( rect.origin.x + rect.size.width - 1.5, 7 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 1.5, rect.origin.y + rect.size.height - 7  ) ];
																					   
			// Draw Inline
			[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 7, 4.5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 8, 4.5 ) ];
			[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 7, rect.origin.y + rect.size.height - 5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 8, rect.origin.y + rect.size.height - 4.5  ) ];
			[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 4.5, 7 ) toPoint:NSMakePoint( 4.5, rect.origin.y + rect.size.height - 8 ) ];
			[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( rect.origin.x + rect.size.width - 4.5, 7 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 4.5, rect.origin.y + rect.size.height - 8  ) ];
			
			[myFontColor set];
			[[self partName] drawAtPoint:titleRect withAttributes:attrs];

			break;		
			
		case PXIPartStylePopup:
			// Draw a popup button.

			titleRect = NSMakePoint( trueRect.origin.x, trueRect.origin.y + ( trueRect.size.height / 2 ) - ( [[self partName] sizeWithAttributes:attrs].height / 2 ) );
			[myFontColor set];
			[[self partName] drawAtPoint:titleRect withAttributes:attrs];
			
			[myForeColor set];
			
			[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + 2 + [self titleWidth], trueRect.origin.y, trueRect.size.width - 2 - [self titleWidth], trueRect.size.height - 2)];
			[[NSColor whiteColor] set];
			[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + [self titleWidth], trueRect.origin.y + 1, trueRect.size.width - 1 - [self titleWidth], trueRect.size.height - 1)];
			[myForeColor set];
			[NSBezierPath strokeRect:NSMakeRect( trueRect.origin.x + [self titleWidth], trueRect.origin.y + 1, trueRect.size.width - 1 - [self titleWidth], trueRect.size.height - 1)];

			[popuparrow compositeToPoint:NSMakePoint( trueRect.origin.x + trueRect.size.width - 18, ( trueRect.size.height / 2 ) - 3 ) operation:NSCompositeCopy];
			
			break;
			
		}
		
	} 
	else
	{
		
		/********************************************************************
							HILITED DRAWING ROUTINES
        ********************************************************************/
		
		switch ( [self partStyle] )
		{
			case PXIPartStyleTransparent: // Transparent
			case PXIPartStyleOpaque: // Opaque
			case PXIPartStyleRectangle: // Rectangle
				[myForeColor set];
				[NSBezierPath fillRect:trueRect];
				
				[myFontColor set];
				[[self partName] drawAtPoint:titleRect withAttributes:attrs];
				break;
				
			case PXIPartStyleRoundRect:
				// Draw a round rect.
				
				// Draw opaque interior.
				//[[NSColor whiteColor] set];
				[myForeColor set];
				[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + 7, trueRect.origin.y, trueRect.size.width - 14, trueRect.size.height ) ];
				[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x, trueRect.origin.y + 7, trueRect.size.width, trueRect.size.height - 14 ) ];
				
				//[[NSColor blackColor] set];
				//[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + 3.5, trueRect.origin.y + 3.5, trueRect.size.width - 7, trueRect.size.height - 7 ) ];
				
				// Draw corners
				[hl_rndcorners compositeToPoint:NSMakePoint( 0, 0 ) fromRect:NSMakeRect( 0, 0, 7, 7 ) operation:NSCompositeSourceOver];
				[hl_rndcorners compositeToPoint:NSMakePoint( 0, rect.origin.y + rect.size.height - 7 ) fromRect:NSMakeRect( 0, 7, 7, 7 ) operation:NSCompositeSourceOver];
				[hl_rndcorners compositeToPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, 0 ) fromRect:NSMakeRect( 7, 0, 7, 7 ) operation:NSCompositeSourceOver];
				[hl_rndcorners compositeToPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, rect.origin.y + rect.size.height - 7 ) fromRect:NSMakeRect( 7, 7, 7, 7 ) operation:NSCompositeSourceOver];
				
				// Draw Outline
				[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 7, 0.5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, 0.5 ) ];
				[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 7, rect.origin.y + rect.size.height - 0.5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, rect.origin.y + rect.size.height - 0.5  ) ];
				[[NSBezierPath setDefaultLineWidth:2] strokeLineFromPoint:NSMakePoint( 0.5, 7 ) toPoint:NSMakePoint( 0.5, rect.origin.y + rect.size.height - 7 ) ];
				[[NSBezierPath setDefaultLineWidth:2] strokeLineFromPoint:NSMakePoint( rect.origin.x + rect.size.width - 0.5, 7 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 0.5, rect.origin.y + rect.size.height - 7  ) ];
								
				[myFontColor set];
				[[self partName] drawAtPoint:titleRect withAttributes:attrs];

				break;
				
			case PXIPartStyleShadow:
				// Draw a shadow button.
				[myForeColor set];
				[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + 2, trueRect.origin.y, trueRect.size.width - 2, trueRect.size.height - 2)];
				[myForeColor set];
				[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x, trueRect.origin.y + 1, trueRect.size.width - 1, trueRect.size.height - 1)];
				
				[myFontColor set];
				[[self partName] drawAtPoint:titleRect withAttributes:attrs];
				break;				
				
			case PXIPartStyleCheckBox:
				// Draw a check box.
				[checkon compositeToPoint:NSMakePoint( 3, ( trueRect.size.height / 2 ) - 6 ) operation:NSCompositeCopy];

				titleRect = NSMakePoint( trueRect.origin.x + 19, trueRect.origin.y + ( trueRect.size.height / 2 ) - ( [[self partName] sizeWithAttributes:attrs].height / 2 ) );
				[[NSColor blackColor] set];
				[[self partName] drawAtPoint:titleRect withAttributes:attrs];
				
				break;
				
			case PXIPartStyleRadioButton:
				// Draw a radio button.
				[radioon compositeToPoint:NSMakePoint( 3, ( trueRect.size.height / 2 ) - 6 ) operation:NSCompositeCopy];

				titleRect = NSMakePoint( trueRect.origin.x + 19, trueRect.origin.y + ( trueRect.size.height / 2 ) - ( [[self partName] sizeWithAttributes:attrs].height / 2 ) );
				[[NSColor blackColor] set];
				[[self partName] drawAtPoint:titleRect withAttributes:attrs];
				
				break;
				
			case PXIPartStyleStandard:
				// Draw a standard button.
				
				// Draw opaque interior.
				[myForeColor set];
				[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + 7, trueRect.origin.y, trueRect.size.width - 14, trueRect.size.height ) ];
				[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x, trueRect.origin.y + 7, trueRect.size.width, trueRect.size.height - 14 ) ];		
								
				// Draw corners
				[hl_stdcorners compositeToPoint:NSMakePoint( 0, 0 ) fromRect:NSMakeRect( 0, 0, 7, 7 ) operation:NSCompositeSourceOver];
				[hl_stdcorners compositeToPoint:NSMakePoint( 0, rect.origin.y + rect.size.height - 7 ) fromRect:NSMakeRect( 0, 7, 7, 7 ) operation:NSCompositeSourceOver];
				[hl_stdcorners compositeToPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, 0 ) fromRect:NSMakeRect( 7, 0, 7, 7 ) operation:NSCompositeSourceOver];
				[hl_stdcorners compositeToPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, rect.origin.y + rect.size.height - 7 ) fromRect:NSMakeRect( 7, 7, 7, 7 ) operation:NSCompositeSourceOver];
				
				// Draw Outline
				[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 7, 1 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, 0.5 ) ];
				[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 7, rect.origin.y + rect.size.height - 0.5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, rect.origin.y + rect.size.height - 0.5 ) ];
				[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 0, 7 ) toPoint:NSMakePoint( 0.5, rect.origin.y + rect.size.height - 7 ) ];
				[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( rect.origin.x + rect.size.width - 0.5, 7 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 0.5, rect.origin.y + rect.size.height - 7  ) ];

				[myFontColor set];
				[[self partName] drawAtPoint:titleRect withAttributes:attrs];

				break;
			case PXIPartStyleDefault:		
				// Draw a default button.
				
				// Draw opaque interior.
				[[NSColor whiteColor] set];
				[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + 7, trueRect.origin.y, trueRect.size.width - 14, trueRect.size.height ) ];
				[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x, trueRect.origin.y + 7, trueRect.size.width, trueRect.size.height - 14 ) ];

				[myForeColor set];
				[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + 3.5, trueRect.origin.y + 3.5, trueRect.size.width - 7, trueRect.size.height - 7 ) ];
				
				// Draw corners
				[hl_defcorners compositeToPoint:NSMakePoint( 0, 0 ) fromRect:NSMakeRect( 0, 0, 7, 7 ) operation:NSCompositeSourceOver];
				[hl_defcorners compositeToPoint:NSMakePoint( 0, rect.origin.y + rect.size.height - 7 ) fromRect:NSMakeRect( 0, 7, 7, 7 ) operation:NSCompositeSourceOver];
				[hl_defcorners compositeToPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, 0 ) fromRect:NSMakeRect( 7, 0, 7, 7 ) operation:NSCompositeSourceOver];
				[hl_defcorners compositeToPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, rect.origin.y + rect.size.height - 7 ) fromRect:NSMakeRect( 7, 7, 7, 7 ) operation:NSCompositeSourceOver];
				
				// Draw Outline
				[[NSBezierPath setDefaultLineWidth:3] strokeLineFromPoint:NSMakePoint( 7, 1.5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, 1.5 ) ];
				[[NSBezierPath setDefaultLineWidth:3] strokeLineFromPoint:NSMakePoint( 7, rect.origin.y + rect.size.height - 1.5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 7, rect.origin.y + rect.size.height - 1.5  ) ];
				[[NSBezierPath setDefaultLineWidth:3] strokeLineFromPoint:NSMakePoint( 1.5, 7 ) toPoint:NSMakePoint( 1.5, rect.origin.y + rect.size.height - 7 ) ];
				[[NSBezierPath setDefaultLineWidth:3] strokeLineFromPoint:NSMakePoint( rect.origin.x + rect.size.width - 1.5, 7 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 1.5, rect.origin.y + rect.size.height - 7  ) ];
				
				// Draw Inline
				[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 7, 4.5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 8, 4.5 ) ];
				[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 7, rect.origin.y + rect.size.height - 5 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 8, rect.origin.y + rect.size.height - 4.5  ) ];
				[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( 4.5, 7 ) toPoint:NSMakePoint( 4.5, rect.origin.y + rect.size.height - 8 ) ];
				[[NSBezierPath setDefaultLineWidth:1] strokeLineFromPoint:NSMakePoint( rect.origin.x + rect.size.width - 4.5, 7 ) toPoint:NSMakePoint( rect.origin.x + rect.size.width - 4.5, rect.origin.y + rect.size.height - 8  ) ];
				
				[myFontColor set];
				[[self partName] drawAtPoint:titleRect withAttributes:attrs];
				
				break;		
				
			case PXIPartStylePopup:
				// Draw a popup button.
				
				[myForeColor set];
				
				titleRect = NSMakePoint( trueRect.origin.x, trueRect.origin.y + ( trueRect.size.height / 2 ) - ( [[self partName] sizeWithAttributes:attrs].height / 2 ) );
				[[self partName] drawAtPoint:titleRect withAttributes:attrs];
				
				[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + 2 + [self titleWidth], trueRect.origin.y, trueRect.size.width - 2 - [self titleWidth], trueRect.size.height - 2)];
				[[NSColor whiteColor] set];
				[NSBezierPath fillRect:NSMakeRect( trueRect.origin.x + [self titleWidth], trueRect.origin.y + 1, trueRect.size.width - 1 - [self titleWidth], trueRect.size.height - 1)];
				[myForeColor set];
				[NSBezierPath strokeRect:NSMakeRect( trueRect.origin.x + [self titleWidth], trueRect.origin.y + 1, trueRect.size.width - 1 - [self titleWidth], trueRect.size.height - 1)];
				
				[popuparrow compositeToPoint:NSMakePoint( trueRect.origin.x + trueRect.size.width - 18, ( trueRect.size.height / 2 ) - 3 ) operation:NSCompositeCopy];
				
				break;
		}
	}
	
	/***************************************************************
						DISABLED PATCH
		This is vastly oversimplified. We need to go back and make
		control-specific disabled code, but I'm too tired right now.
		
	***************************************************************/
	
	if ( ! [self enabled] )
	{
		[myDisabledOverlay set];
		NSRectFillUsingOperation( trueRect, NSCompositeSourceAtop );
	}
	
	if ( [ gPXIWorld currentTool ] == 1 )
	{
		[[NSColor blackColor] set];
		[NSBezierPath strokeRect:trueRect];
	}	
	 
	[gbuffer unlockFocus];
	[gbuffer compositeToPoint:NSMakePoint(0,0) operation:NSCompositeSourceOver];
	[gbuffer release];
	
}

- (void) mouseDown:(NSEvent*)theEvent
{
	NSLog( @"%@ : mouseDown", [self partName]);

	NSPoint fudgeFactor = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil];
	
	while ( [[self window] nextEventMatchingMask:NSLeftMouseUpMask untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES] == nil )
	{
		
		if ( [gPXIWorld currentTool] == 1 )
		{
			
			NSPoint newLocation = [[self window] mouseLocationOutsideOfEventStream];
			
			[self setFrame:NSMakeRect( newLocation.x - fudgeFactor.x, [[self window] frame].size.height - newLocation.y - [self frame].size.height - ( [self frame].size.height - fudgeFactor.y ), [self frame].size.width, [self frame].size.height )];
			[[self window] display];
			
		}
		else
		{
			if ( [self autoHilite] )
			{
				if ( NSPointInRect( [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:nil], [self bounds] ) )
				{
					[self setHilite:YES];
					[self setNeedsDisplay:YES];
				}
				else
				{
					[self setHilite:NO];
					[self setNeedsDisplay:YES];				
				}
			}
			NSLog( @"%@ : mouseStillDown", [self partName]);
		}
	}

	if ( [self autoHilite] )
	{
		[self setHilite:NO];
		[self setNeedsDisplay:YES];
	}
	
	NSLog( @"%@ : mouseUp", [self partName]);
	if ( [[self partName] isEqualToString:@"Run Program"] )
	{
		[[self superview] performSelector:@selector(mixMaster)];
	}
}

- (void) mouseEntered:(NSEvent*)theEvent
{
	NSLog( @"%@ : mouseEnter", [self partName]);
}

- (void) mouseExited:(NSEvent*)theEvent
{
	NSLog( @"%@ : mouseLeave", [self partName]);
}

- (void)dealloc
{
	[defcorners release];
	[stdcorners release];
	[rndcorners release];
	[hl_defcorners release];
	[hl_stdcorners release];
	[hl_rndcorners release];
	
	[checkon release];
	[checkoff release];
	[checkclick release];
	
	[radioon release];
	[radiooff release];
	[radioclick release];
	[whitegraypat release];
	[super dealloc];
}

@end
